﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Utilities;
using ComboBox = System.Windows.Controls.ComboBox;
using TextBox = System.Windows.Controls.TextBox;

namespace Views
{
    partial class FormWindow : Window
    {
        public Form Form { get; set; }
        private object _firstItem;
        private TextBox _selectedTextBox;

        public FormWindow(Form form)
        {
            InitializeComponent();    

            Form = form;

            AddAllControls();
            SetWindowStyle();
        }

        public void AddAllControls()
        {
            foreach (var item in Form.Items)
            {
                Label itemLabel = GetItemLabel(item.Label);
                UIElement control = GetItemControl(item);

                StackPanel wrapperPanel = GetStackPanelWrapper();
                wrapperPanel.Children.Add(itemLabel);
                wrapperPanel.Children.Add(control);

                // tilføjer stack panel til main stack panel, som er defineret i xaml
                StackPanelParent.Children.Add(wrapperPanel);

                if (_firstItem == null)
                {
                    _firstItem = control;
                }
            }

            var successButton = GetSuccessButton();
            var failureButton = GetFailureButton();

            StackPanel buttonStackPanel = GetStackPanelWrapper();
            buttonStackPanel.Children.Add(failureButton);
            buttonStackPanel.Children.Add(successButton);
            StackPanelParent.Children.Add(buttonStackPanel);

            FocusFirstItem();
        }

        // henter det stack panel der skal wrappe label+control
        public StackPanel GetStackPanelWrapper()
        {
            var stack = new StackPanel
            {
                Height = 50,
                Margin = new Thickness(10, 10, 0, 0),
                Orientation = Orientation.Horizontal
            };

            return stack;
        }

        // henter label til hver control
        public Label GetItemLabel(string content)
        {
            var label = new Label
            {
                Height = 30,
                Width = 140,
                FontSize = 14,
                VerticalContentAlignment = VerticalAlignment.Center,
                HorizontalContentAlignment = HorizontalAlignment.Left,
                Content = content
            };
            
            return label;
        }

        // tager et formitem, og finder passende WPF control
        public UIElement GetItemControl(FormItem item)
        {
            if (item.Control is Utilities.ComboBox)
            {
                var control = (Utilities.ComboBox) item.Control;
                return GetComboBox(control, item.Name);
            }

            if (item.Control is Utilities.TextBox)
            {
                var control = (Utilities.TextBox) item.Control;
                return GetTextBox(control, item.Name);
            }

            if (item.Control is DisabledTextBox)
            {
                var control = (DisabledTextBox) item.Control;
                return GetDisabledTextBox(control);
            }

            if (item.Control is IntegerBox)
            {
                var control = (IntegerBox) item.Control;
                return GetIntegerBox(control, item.Name);
            }

            if (item.Control is DateBox)
            {
                var control = (DateBox) item.Control;
                return GetDateBox(control, item.Name);
            }

            return null;
        }

        public ComboBox GetComboBox(Utilities.ComboBox control, string name)
        {
            var comboBox = new ComboBox
            {
                ItemsSource = control.Items,
                DisplayMemberPath = control.DisplayMemberPath,
                Margin = new Thickness(20, 0, 0, 0),
                Height = 30,
                VerticalContentAlignment = VerticalAlignment.Center,
                Width = 200
            };

            comboBox.SelectionChanged += (sender, args) =>
            {
                Form.Result[name] = comboBox.SelectedItem;
            };

            if (control.SelectedItem != null)
            {
                foreach (var comboBoxItem in comboBox.Items)
                {
                    if (comboBoxItem == control.SelectedItem)
                    {
                        comboBox.SelectedItem = control.SelectedItem;
                    }
                }
            }

            return comboBox;
        }

        public TextBox GetTextBox(Utilities.TextBox control, string name)
        {
            var textBox = new TextBox
            {
                Text = control.DefaultText,
                Height = 30,
                FontSize = 14,
                VerticalContentAlignment = VerticalAlignment.Center,
                Margin = new Thickness(20, 0, 0, 0),
                Width = 200
            };

            textBox.TextChanged += (sender, args) =>
            {
                Form.Result[name] = textBox.Text;
            };

            if (control.Selected) _selectedTextBox = textBox;

            return textBox;
        }

        public TextBox GetDisabledTextBox(DisabledTextBox control)
        {
            var textBox = new TextBox
            {
                Text = control.DefaultText,
                IsEnabled = false,
                Height = 30,
                FontSize = 14,
                VerticalContentAlignment = VerticalAlignment.Center,
                Margin = new Thickness(20, 0, 0, 0),
                Width = 200
            };

            return textBox;
        }

        public TextBox GetIntegerBox(IntegerBox control, string name)
        {
            var textBox = new TextBox
            {
                Text = control.DefaultText,
                Height = 30,
                FontSize = 14,
                VerticalContentAlignment = VerticalAlignment.Center,
                Margin = new Thickness(20, 0, 0, 0),
                Width = 200
            };

            textBox.TextChanged += (sender, args) =>
            {
                var newText = textBox.Text.Where(c => Char.IsDigit(c))
                         .Aggregate(String.Empty, (current, c) => current + c);
                textBox.Text = newText;
            };

            textBox.TextChanged += (sender, args) =>
            {
                Form.Result[name] = textBox.Text;
            };

            return textBox;
        }

        public DatePicker GetDateBox(DateBox control, string name)
        {
            var datePicker = new DatePicker
            {
                Height = 30,
                FontSize = 14,
                VerticalContentAlignment = VerticalAlignment.Center,
                Margin = new Thickness(20, 0, 0, 0),
                Width = 200,
                SelectedDate = control.defaultDate
            };

            datePicker.SelectedDateChanged += (sender, args) =>
            {
                Form.Result[name] = datePicker.SelectedDate;
            };

            return datePicker;
        }

        public Button GetSuccessButton()
        {
            var button = new Button
            {
                Width = 200,
                Height = 40,
                Content = Form.BtnSubmit,
                Style = Resources["BtnWindowsStyle"] as Style,
                VerticalContentAlignment = VerticalAlignment.Center,
                IsDefault = true,
                Margin = new Thickness(20, 0, 0, 0)
            };

            button.Click += (sender, args) =>
            {
                this.DialogResult = true;
            };

            return button;
        }

        public Button GetFailureButton()
        {
            var button = new Button
            {
                Width = 140,
                Height = 40,
                Content = Form.BtnExit,
                IsCancel = true,
                Style = Resources["BtnWindowsStyle"] as Style,
                VerticalContentAlignment = VerticalAlignment.Center,
                Margin = new Thickness(0, 0, 0, 0)
            };

            button.Click += (sender, args) =>
            {
                this.DialogResult = false;
            };

            return button;
        }

        public void FocusFirstItem()
        {
            if (_firstItem is ComboBox)
            {
                ((ComboBox) _firstItem).Focus();
            }

            if (_firstItem is TextBox)
            {
                ((TextBox) _firstItem).Focus();
            }

            if (_selectedTextBox != null)
            {
                _selectedTextBox.SelectAll();
            }
        }

        public void SetWindowStyle()
        {
            Height = 60 * Form.Items.Count + 100;
            Width = 386;
            Title = Form.Title;
            ResizeMode = ResizeMode.NoResize;
            WindowStartupLocation = WindowStartupLocation.CenterScreen;
            StackPanelParent.Margin = new Thickness(0, 0, 0, 0);
        }

        public void BtnSuccess(object sender, EventArgs args)
        {
            DialogResult = true;
        }

        public void BtnFail(object sender, EventArgs args)
        {
            DialogResult = false;
        }
    }
}
